package com.ehotting.eaf.core.utils;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class RsaUtils {

    /**
     * 私钥加密
     * @param prk 私钥字符串
     * @param content 需要加密的内容
     * @return
     * @throws Exception
     */
    public static String encrypt(String prk,String content) throws Exception {

        byte[] privateKeyBytes = prk.getBytes();
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyBytes));

        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, priKey);

        byte[] result = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * 公钥解密
     * @param puk 公钥字符串
     * @param signEncrypt 加密后的内容
     * @return
     */
    public static String decrypt(String puk,String signEncrypt) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        byte[] publickKeyBytes = puk.getBytes();
        X509EncodedKeySpec x = new X509EncodedKeySpec(Base64.getDecoder().decode(publickKeyBytes));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey pubKey = keyFactory.generatePublic(x);

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, pubKey);

        byte[] result = cipher.doFinal(Base64.getDecoder().decode(signEncrypt));
        return new String(result);
    }

    /**
     * 公钥加密
     * @param pub 公钥字符串
     * @param content 需要加密的内容
     * @return
     * @throws Exception
     */
    public static String encryptWithpub(String pub,String content) throws Exception {

        byte[] publicKeyBytes = pub.getBytes();
        X509EncodedKeySpec x = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyBytes));

        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey pubKey = keyFactory.generatePublic(x);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);

        byte[] result = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * 私钥解密
     * @param prk 私钥字符串
     * @param signEncrypt 加密后的内容
     * @return
     */
    public static String decryptWithPrk(String prk,String signEncrypt) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        byte[] privateKeyBytes = prk.getBytes();
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyBytes));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, priKey);

        byte[] result = cipher.doFinal(Base64.getDecoder().decode(signEncrypt));
        return new String(result);
    }

    /**
     * RSA签名
     * @param prk 私钥
     * @param content 待签名内容
     * @return
     */
    public static String sign(String prk,String content) throws Exception{
        byte[] keyBytes = prk.getBytes();
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(keyBytes));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey key = keyFactory.generatePrivate(keySpec);
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initSign(key);
        signature.update(content.getBytes());
        Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(signature.sign());
    }

    /**
     * 验签
     * @param srcData 原始字符串
     * @param pub 公钥
     * @param sign 签名
     * @return 是否验签通过
     */
    public static boolean verify(String srcData, String pub, String sign) throws Exception {
        byte[] keyBytes = pub.getBytes();
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(keyBytes));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey key = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initVerify(key);
        signature.update(srcData.getBytes());
        Base64.Decoder decoder = Base64.getDecoder();
        return signature.verify(decoder.decode(sign.getBytes()));

    }
}
